<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>智能客户关系管理助手 - 数据字典</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }

    :root {
      --primary: #4361ee;
      --secondary: #3f37c9;
      --accent: #4895ef;
      --dark: #1e1e2c;
      --darker: #14141f;
      --light: #f8f9fa;
      --success: #4caf50;
      --warning: #ff9800;
      --danger: #f44336;
      --gray: #6c757d;
      --border-radius: 8px;
      --transition: all 0.3s ease;
      --product-1: #ff6b6b;
      --product-2: #4ecdc4;
      --product-3: #ffd166;
      --product-4: #6a0572;
    }

    body {
      background-color: var(--darker);
      color: var(--light);
      display: flex;
      min-height: 100vh;
    }

    /* 侧边栏样式 */
    .sidebar {
      width: 250px;
      background-color: var(--dark);
      padding: 20px 0;
      height: 100vh;
      position: fixed;
      transition: var(--transition);
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
      z-index: 100;
    }

    .logo-container {
      display: flex;
      align-items: center;
      padding: 0 20px 20px;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      margin-bottom: 20px;
    }

    .logo {
      width: 40px;
      height: 40px;
      background: linear-gradient(135deg, var(--accent), var(--primary));
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 10px;
    }

    .logo i {
      font-size: 20px;
    }

    .logo-text {
      font-size: 20px;
      font-weight: 700;
      background: linear-gradient(to right, var(--accent), var(--primary));
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }

    .nav-links {
      list-style: none;
      padding: 0 15px;
    }

    .nav-links li {
      margin-bottom: 5px;
    }

    .nav-links a {
      display: flex;
      align-items: center;
      padding: 12px 15px;
      text-decoration: none;
      color: rgba(255, 255, 255, 0.7);
      border-radius: var(--border-radius);
      transition: var(--transition);
    }

    .nav-links a:hover, .nav-links a.active {
      background-color: rgba(67, 97, 238, 0.2);
      color: var(--light);
    }

    .nav-links a i {
      margin-right: 10px;
      width: 20px;
      text-align: center;
    }

    /* 主内容区样式 */
    .main-content {
      flex: 1;
      margin-left: 250px;
      padding: 20px;
      transition: var(--transition);
    }

    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 30px;
      padding-bottom: 15px;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .page-title {
      font-size: 24px;
      font-weight: 600;
      display: flex;
      align-items: center;
    }

    .page-title i {
      margin-right: 10px;
      color: var(--accent);
    }

    .user-actions {
      display: flex;
      align-items: center;
      gap: 15px;
    }

    .user-id-input {
      display: flex;
      gap: 10px;
      align-items: center;
      background-color: rgba(255, 255, 255, 0.08);
      padding: 8px 15px;
      border-radius: 30px;
    }

    .user-id-input input {
      background: transparent;
      border: none;
      color: white;
      font-size: 14px;
      width: 120px;
    }

    .user-id-input input::placeholder {
      color: rgba(255, 255, 255, 0.6);
    }

    .user-id-input button {
      background: var(--primary);
      border: none;
      color: white;
      padding: 5px 10px;
      border-radius: 20px;
      font-size: 12px;
      cursor: pointer;
    }

    .search-container {
      display: flex;
      flex-direction: column;
    }

    .search-container label {
      font-size: 14px;
      margin-bottom: 5px;
      opacity: 0.8;
    }

    .search-box {
      position: relative;
      height: 40px;
      display: flex;
      align-items: center;
    }

    .search-box input {
      background-color: rgba(255, 255, 255, 0.08);
      border: none;
      padding: 0 15px 0 40px;
      border-radius: 30px;
      color: var(--light);
      width: 250px;
      height: 100%;
      line-height: 1;
      margin: 0;
      transition: var(--transition);
    }

    .search-box input:focus {
      outline: none;
      background-color: rgba(255, 255, 255, 0.15);
      width: 300px;
    }

    .search-box i {
      position: absolute;
      left: 15px;
      top: 50%;
      transform: translateY(-50%);
      color: rgba(255, 255, 255, 0.5);
      margin: 0;
    }

    .user-profile {
      display: flex;
      align-items: center;
      background-color: rgba(255, 255, 255, 0.08);
      padding: 8px 15px;
      border-radius: 30px;
      cursor: pointer;
      transition: var(--transition);
    }

    .user-profile:hover {
      background-color: rgba(255, 255, 255, 0.15);
    }

    .user-profile img {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      margin-right: 10px;
      object-fit: cover;
    }

    /* 卡片样式 */
    .card {
      background-color: var(--dark);
      border-radius: var(--border-radius);
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
      margin-bottom: 25px;
      overflow: hidden;
    }

    .card-header {
      padding: 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .card-title {
      font-size: 18px;
      font-weight: 600;
    }

    .card-body {
      padding: 20px;
    }

    /* 数据字典管理区域 */
    .dictionary-management {
      display: flex;
      flex-direction: column;
      gap: 20px;
    }

    .action-bar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }

    .filters {
      display: flex;
      gap: 15px;
      flex-wrap: wrap;
      margin-bottom: 20px;
      background-color: rgba(255, 255, 255, 0.05);
      padding: 15px;
      border-radius: var(--border-radius);
    }

    .filter-group {
      display: flex;
      flex-direction: column;
      min-width: 200px;
    }

    .filter-group label {
      font-size: 14px;
      margin-bottom: 5px;
      opacity: 0.8;
    }

    .filter-group select, .filter-group input {
      background-color: rgba(255, 255, 255, 0.08);
      border: none;
      padding: 10px 15px;
      border-radius: var(--border-radius);
      color: var(--light);
    }

    .filter-group select:focus, .filter-group input:focus {
      outline: none;
      background-color: rgba(255, 255, 255, 0.12);
    }

    /* 数据卡片网格 */
    .dictionary-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 20px;
      margin-bottom: 25px;
    }

    .dictionary-card {
      background: var(--dark);
      border-radius: var(--border-radius);
      overflow: hidden;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
      transition: var(--transition);
      display: flex;
      flex-direction: column;
      height: 100%;
      border-left: 4px solid var(--accent);
    }

    .dictionary-card:hover {
      transform: translateY(-5px);
      box-shadow: 0 8px 25px rgba(67, 97, 238, 0.3);
    }

    .dictionary-header {
      padding: 20px;
      background-color: rgba(67, 97, 238, 0.1);
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .dictionary-name {
      font-size: 18px;
      font-weight: 600;
      color: var(--light);
    }

    .dictionary-category {
      font-size: 14px;
      color: var(--accent);
      background: rgba(67, 97, 238, 0.1);
      padding: 3px 8px;
      border-radius: 20px;
    }

    .dictionary-info {
      padding: 20px;
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }

    .dictionary-row {
      display: flex;
      justify-content: space-between;
      padding-bottom: 8px;
      border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    }

    .dictionary-label {
      font-weight: 500;
      color: rgba(255, 255, 255, 0.7);
    }

    .dictionary-value {
      color: var(--light);
      text-align: right;
      max-width: 60%;
      word-break: break-word;
    }

    .dictionary-description {
      margin-top: 10px;
      padding: 12px;
      background-color: rgba(255, 255, 255, 0.05);
      border-radius: var(--border-radius);
      color: rgba(255, 255, 255, 0.8);
      font-size: 14px;
      line-height: 1.5;
    }

    .dictionary-actions {
      display: flex;
      justify-content: flex-end;
      padding: 15px;
      background: rgba(255, 255, 255, 0.05);
      gap: 10px;
    }

    /* 表格样式 */
    .table-container {
      overflow-x: auto;
      border-radius: var(--border-radius);
      background-color: rgba(255, 255, 255, 0.05);
    }

    table {
      width: 100%;
      border-collapse: collapse;
      min-width: 1000px;
    }

    th, td {
      padding: 12px 15px;
      text-align: left;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    th {
      background-color: rgba(67, 97, 238, 0.2);
      font-weight: 600;
      color: var(--accent);
    }

    tr:hover {
      background-color: rgba(255, 255, 255, 0.05);
    }

    .status-badge {
      display: inline-block;
      padding: 4px 10px;
      border-radius: 20px;
      font-size: 12px;
      font-weight: 500;
    }

    .status-active {
      background-color: rgba(76, 175, 80, 0.2);
      color: var(--success);
    }

    .status-inactive {
      background-color: rgba(244, 67, 54, 0.2);
      color: var(--danger);
    }

    .actions {
      display: flex;
      gap: 8px;
    }

    .action-btn {
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      border: none;
      background-color: rgba(255, 255, 255, 0.1);
      color: var(--light);
      cursor: pointer;
      transition: var(--transition);
    }

    .action-btn:hover {
      background-color: var(--accent);
    }

    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 10px 20px;
      border-radius: var(--border-radius);
      border: none;
      cursor: pointer;
      font-weight: 500;
      transition: var(--transition);
    }

    .btn i {
      margin-right: 8px;
    }

    .btn-primary {
      background-color: var(--primary);
      color: white;
    }

    .btn-primary:hover {
      background-color: var(--secondary);
    }

    .btn-success {
      background-color: var(--success);
      color: white;
    }

    .btn-warning {
      background-color: var(--warning);
      color: white;
    }

    .btn-danger {
      background-color: var(--danger);
      color: white;
    }

    .btn-outline {
      background-color: transparent;
      border: 1px solid rgba(255, 255, 255, 0.2);
      color: rgba(255, 255, 255, 0.7);
    }

    .btn-outline:hover {
      background-color: rgba(255, 255, 255, 0.1);
      color: var(--light);
    }

    .loading {
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 20px;
    }

    .spinner {
      width: 24px;
      height: 24px;
      border: 3px solid rgba(255, 255, 255, 0.3);
      border-radius: 50%;
      border-top-color: var(--accent);
      animation: spin 1s linear infinite;
      margin-right: 10px;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    /* 模态框样式 */
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.7);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1000;
    }

    .modal {
      background-color: var(--dark);
      width: 90%;
      max-width: 800px;
      border-radius: var(--border-radius);
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
      overflow: hidden;
    }

    .modal-header {
      padding: 20px;
      background-color: rgba(67, 97, 238, 0.2);
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .modal-title {
      font-size: 18px;
      font-weight: 600;
      color: var(--accent);
    }

    .modal-close {
      background: none;
      border: none;
      color: var(--light);
      font-size: 20px;
      cursor: pointer;
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      transition: var(--transition);
    }

    .modal-close:hover {
      background-color: rgba(255, 255, 255, 0.1);
    }

    .modal-body {
      padding: 20px;
      max-height: 70vh;
      overflow-y: auto;
    }

    .form-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 20px;
    }

    .form-group {
      margin-bottom: 15px;
    }

    .form-group label {
      display: block;
      margin-bottom: 8px;
      font-size: 14px;
      opacity: 0.9;
    }

    .form-group input, .form-group select, .form-group textarea {
      width: 100%;
      padding: 12px 15px;
      background-color: rgba(255, 255, 255, 0.08);
      border: none;
      border-radius: var(--border-radius);
      color: var(--light);
    }

    .form-group textarea {
      height: 100px;
      resize: vertical;
    }

    .form-group input:focus, .form-group select:focus, .form-group textarea:focus {
      outline: none;
      background-color: rgba(255, 255, 255, 0.12);
    }

    .modal-footer {
      padding: 15px 20px;
      background-color: rgba(255, 255, 255, 0.05);
      display: flex;
      justify-content: flex-end;
      gap: 10px;
    }

    /* 统计卡片样式 */
    .stats-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 20px;
      margin-bottom: 25px;
    }

    .stat-card {
      background: var(--dark);
      border-radius: var(--border-radius);
      padding: 20px;
      display: flex;
      flex-direction: column;
      box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
    }

    .stat-value {
      font-size: 28px;
      font-weight: 700;
      margin-bottom: 10px;
    }

    .stat-label {
      font-size: 14px;
      color: rgba(255, 255, 255, 0.7);
    }

    .stat-icon {
      width: 50px;
      height: 50px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 15px;
      font-size: 20px;
    }

    .stat-icon.entries {
      background: rgba(67, 97, 238, 0.2);
      color: var(--accent);
    }

    .stat-icon.categories {
      background: rgba(255, 107, 107, 0.2);
      color: var(--product-1);
    }

    .stat-icon.active {
      background: rgba(76, 175, 80, 0.2);
      color: var(--success);
    }

    .stat-icon.updated {
      background: rgba(255, 152, 0, 0.2);
      color: var(--warning);
    }

    /* 响应式设计 */
    @media (max-width: 992px) {
      .sidebar {
        width: 80px;
      }

      .logo-text, .link-text {
        display: none;
      }

      .nav-links a {
        justify-content: center;
      }

      .nav-links a i {
        margin-right: 0;
        font-size: 20px;
      }

      .main-content {
        margin-left: 80px;
      }

      .filters {
        flex-direction: column;
      }
    }

    @media (max-width: 768px) {
      .search-box input {
        width: 150px;
      }

      .search-box input:focus {
        width: 180px;
      }

      .header {
        flex-direction: column;
        align-items: flex-start;
        gap: 15px;
      }

      .user-actions {
        width: 100%;
        justify-content: space-between;
      }

      .action-bar {
        flex-direction: column;
        align-items: flex-start;
        gap: 15px;
      }

      .dictionary-grid {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>
<!-- 侧边导航 -->
<div class="sidebar">
  <div class="logo-container">
    <div class="logo">
      <i class="fas fa-brain"></i>
    </div>
    <div class="logo-text">智能CRM</div>
  </div>

  <ul class="nav-links">
    <li><a href="/main"><i class="fas fa-home"></i> <span class="link-text">AI助手</span></a></li>
    <li><a href="/customer"><i class="fas fa-users"></i> <span class="link-text">客户管理</span></a></li>
    <li><a href="#" class="active"><i class="fas fa-book"></i> <span class="link-text">数据字典</span></a></li>
    <li><a href="/usermanage"><i class="fas fa-user-cog"></i> <span class="link-text">用户管理</span></a></li>
    <li><a href="/product"><i class="fas fa-box"></i> <span class="link-text">产品管理</span></a></li>
    <li><a href="/orderitems"><i class="fas fa-shopping-cart"></i> <span class="link-text">订单管理</span></a></li>
  </ul>
</div>

<!-- 主内容区 -->
<div class="main-content" id="app">
  <!-- 头部区域 -->
  <div class="header">
    <div class="page-title">
      <i class="fas fa-book"></i> 数据字典管理
    </div>

    <div class="user-actions">
      <div class="user-profile">
        <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="用户头像">
        <span th:text="${session.username}"></span>
      </div>
    </div>
  </div>

  <!-- 数据字典管理区域 -->
  <div class="dictionary-management">
    <!-- 统计卡片 -->
    <div class="stats-container">
      <div class="stat-card">
        <div class="stat-icon entries">
          <i class="fas fa-database"></i>
        </div>
        <div class="stat-value">{{ dictionaryEntries.length }}</div>
        <div class="stat-label">数据项总数</div>
      </div>
      <div class="stat-card">
        <div class="stat-icon categories">
          <i class="fas fa-tags"></i>
        </div>
        <div class="stat-value">{{ categories.length }}</div>
        <div class="stat-label">数据类别</div>
      </div>
      <div class="stat-card">
        <div class="stat-icon active">
          <i class="fas fa-check-circle"></i>
        </div>
        <div class="stat-value">{{ activeEntries }}</div>
        <div class="stat-label">启用数据项</div>
      </div>
      <div class="stat-card">
        <div class="stat-icon updated">
          <i class="fas fa-sync-alt"></i>
        </div>
        <div class="stat-value">{{ recentlyUpdated }}</div>
        <div class="stat-label">最近更新</div>
      </div>
    </div>

    <div class="action-bar">
      <h2><i class="fas fa-book"></i> 数据字典项列表</h2>
      <div>
        <button class="btn btn-outline" @click="viewMode = 'grid'" :class="{'btn-primary': viewMode === 'grid'}">
          <i class="fas fa-th"></i> 卡片视图
        </button>
        <button class="btn btn-outline" @click="viewMode = 'table'" :class="{'btn-primary': viewMode === 'table'}">
          <i class="fas fa-table"></i> 表格视图
        </button>
        <button class="btn btn-primary" @click="openAddModal">
          <i class="fas fa-plus"></i> 添加新数据项
        </button>
      </div>
    </div>

    <!-- 筛选区域 -->
    <div class="filters">
      <div class="filter-group">
        <label>数据类别</label>
        <select v-model="filters.category" @change="applyFilters">
          <option value="">全部类别</option>
          <option v-for="category in categories" :value="category">{{ category }}</option>
        </select>
      </div>

      <div class="filter-group">
        <label>数据状态</label>
        <select v-model="filters.active" @change="applyFilters">
          <option value="">全部状态</option>
          <option value="active">启用</option>
          <option value="inactive">停用</option>
        </select>
      </div>

      <div class="filter-group">
        <label>数据类型</label>
        <select v-model="filters.dataType" @change="applyFilters">
          <option value="">全部类型</option>
          <option v-for="type in dataTypes" :value="type">{{ type }}</option>
        </select>
      </div>

      <div class="filter-group">
        <label>创建时间</label>
        <select v-model="filters.timeRange" @change="applyFilters">
          <option value="">全部时间</option>
          <option value="week">最近一周</option>
          <option value="month">最近一个月</option>
          <option value="year">最近一年</option>
        </select>
      </div>
      <div class="search-container">
        <label>搜索：</label>
        <div class="search-box">
          <i class="fas fa-search"></i>
          <input type="text" v-model="searchQuery" placeholder="搜索数据项..." @input="searchDictionary">
        </div>
      </div>
    </div>

    <!-- 数据卡片视图 -->
    <div class="dictionary-grid" v-if="viewMode === 'grid'">
      <div class="dictionary-card" v-for="entry in paginatedEntries" :key="entry.dict_id">
        <div class="dictionary-header">
          <div class="dictionary-name">{{ entry.dict_name }}</div>
          <div class="dictionary-category">{{ entry.dict_type }}</div>
        </div>
        <div class="dictionary-info">
          <div class="dictionary-row">
            <span class="dictionary-label">编码：</span>
            <span class="dictionary-value">{{ entry.dict_code }}</span>
          </div>
          <div class="dictionary-row">
            <span class="dictionary-label">值：</span>
            <span class="dictionary-value">{{ entry.dict_value }}</span>
          </div>
          <div class="dictionary-row">
            <span class="dictionary-label">状态：</span>
            <span class="dictionary-value">
                <span class="status-badge" :class="{'status-active': entry.status === '1', 'status-inactive': entry.status !== '1'}">
                  {{ entry.status === '1' ? '启用' : '停用' }}
                </span>
              </span>
          </div>
          <div class="dictionary-row">
            <span class="dictionary-label">创建时间：</span>
            <span class="dictionary-value">{{ formatDate(entry.create_time) }}</span>
          </div>
        </div>
        <div class="dictionary-actions">
          <button class="action-btn" @click="openEditModal(entry)">
            <i class="fas fa-edit"></i>
          </button>
          <button class="action-btn" @click="toggleEntryStatus(entry)">
            <i class="fas" :class="{'fa-toggle-on': entry.status === '1', 'fa-toggle-off': entry.status !== '1'}"></i>
          </button>
          <button class="action-btn" @click="deleteEntry(entry.dict_id)">
            <i class="fas fa-trash"></i>
          </button>
        </div>
      </div>
    </div>

    <!-- 数据表格视图 -->
    <div class="card" v-if="viewMode === 'table'">
      <div class="table-container">
        <table>
          <thead>
          <tr>
            <th>ID</th>
            <th>名称</th>
            <th>编码</th>
            <th>类别</th>
            <th>值</th>
            <th>状态</th>
            <th>创建时间</th>
            <th>操作</th>
          </tr>
          </thead>
          <tbody>
          <tr v-if="loading">
            <td colspan="8" class="loading">
              <div class="spinner"></div>
              <span>加载数据中...</span>
            </td>
          </tr>
          <tr v-else-if="filteredEntries.length === 0">
            <td colspan="8" style="text-align: center; padding: 30px;">
              没有找到匹配的数据项
            </td>
          </tr>
          <tr v-for="entry in paginatedEntries" :key="entry.dictId">
            <td>{{ entry.dict_id }}</td>
            <td>{{ entry.dict_name }}</td>
            <td>{{ entry.dict_code }}</td>
            <td>{{ entry.dict_type }}</td>
            <td>{{ entry.dict_value }}</td>
            <td>
                  <span class="status-badge" :class="{'status-active': entry.status === '1', 'status-inactive': entry.status !== '1'}">
                    {{ entry.status === '1' ? '启用' : '停用' }}
                  </span>
            </td>
            <td>{{ formatDate(entry.create_time) }}</td>
            <td>
              <div class="actions">
                <button class="action-btn" @click="openEditModal(entry)">
                  <i class="fas fa-edit"></i>
                </button>
                <button class="action-btn" @click="toggleEntryStatus(entry)">
                  <i class="fas" :class="{'fa-toggle-on': entry.active, 'fa-toggle-off': !entry.active}"></i>
                </button>
                <button class="action-btn" @click="deleteEntry(entry.dictId)">
                  <i class="fas fa-trash"></i>
                </button>
              </div>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- 分页控件 -->
    <div class="pagination" v-if="filteredEntries.length > 0" style="display: flex; justify-content: center; align-items: center; margin-top: 20px;">
      <button class="btn btn-outline" :disabled="currentPage === 1" @click="prevPage">
        <i class="fas fa-chevron-left"></i> 上一页
      </button>
      <span style="margin: 0 15px;">第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
      <button class="btn btn-outline" :disabled="currentPage === totalPages" @click="nextPage">
        下一页 <i class="fas fa-chevron-right"></i>
      </button>
    </div>
  </div>

  <!-- 添加/编辑数据项模态框 -->
  <div class="modal-overlay" v-if="showModal">
    <div class="modal">
      <div class="modal-header">
        <div class="modal-title">
          <i class="fas" :class="{'fa-plus': isAdding, 'fa-edit': !isAdding}"></i>
          {{ isAdding ? '添加新数据项' : '编辑数据项' }}
        </div>
        <button class="modal-close" @click="closeModal">
          <i class="fas fa-times"></i>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-grid">
          <div class="form-group">
            <label>数据项名称 *</label>
            <input type="text" v-model="currentEntry.dict_name" placeholder="输入数据项名称">
          </div>
          <div class="form-group">
            <label>数据项编码 *</label>
            <input type="text" v-model="currentEntry.dict_code" placeholder="输入唯一编码">
          </div>
          <div class="form-group">
            <label>数据类别 *</label>
            <select v-model="currentEntry.dict_type">
              <option v-for="category in categories" :value="category">{{ category }}</option>
            </select>
          </div>
          <div class="form-group">
            <label>数据值 *</label>
            <input type="text" v-model="currentEntry.dict_value" placeholder="输入数据值">
          </div>
          <div class="form-group">
            <label>排序</label>
            <input type="number" v-model="currentEntry.sort" placeholder="输入排序值">
          </div>
          <div class="form-group">
            <label>数据状态</label>
            <select v-model="currentEntry.status">
              <option value="1">启用</option>
              <option value="0">停用</option>
            </select>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-outline" @click="closeModal">取消</button>
        <button class="btn btn-primary" @click="saveEntry">
          <i class="fas fa-save"></i> {{ isAdding ? '添加数据项' : '保存更改' }}
        </button>
      </div>
    </div>
  </div>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      userId: 'admin',
      searchQuery: '',
      dictionaryEntries: [],
      filteredEntries: [],
      loading: true,
      showModal: false,
      isAdding: true,
      currentEntry: null,
      currentPage: 1,
      itemsPerPage: 8,
      viewMode: 'grid', // 'grid' or 'table'

      // 筛选条件
      filters: {
        category: '',
        active: '',
        dataType: '',
        timeRange: ''
      },

      // 数据字典分类
      categories: ['系统参数', '客户信息', '产品数据', '订单状态', '用户权限', '区域信息', '其他'],

      // 数据类型
      dataTypes: ['字符串', '整数', '浮点数', '布尔值', '日期', '时间', '日期时间', '枚举']
    },
    computed: {
      activeEntries() {
        return this.dictionaryEntries.filter(e => e.status === '1').length;
      },
      recentlyUpdated() {
        const oneMonthAgo = new Date();
        oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
        return this.dictionaryEntries.filter(e => {
          const updateDate = this.parseDate(e.update_time);
          return updateDate > oneMonthAgo;
        }).length;
      },
      totalPages() {
        return Math.ceil(this.filteredEntries.length / this.itemsPerPage);
      },
      paginatedEntries() {
        const start = (this.currentPage - 1) * this.itemsPerPage;
        const end = start + this.itemsPerPage;
        return this.filteredEntries.slice(start, end);
      }
    },
    mounted() {
      this.fetchDictionaryEntries();
    },
    methods: {
      // 搜索数据项
      searchDictionary() {
        if (!this.searchQuery) {
          this.filteredEntries = [...this.dictionaryEntries];
          return;
        }

        const query = this.searchQuery.toLowerCase();
        this.filteredEntries = this.dictionaryEntries.filter(entry =>
                entry.dictName.toLowerCase().includes(query) ||
                entry.dictCode.toLowerCase().includes(query) ||
                entry.description.toLowerCase().includes(query) ||
                entry.dictType.toLowerCase().includes(query)
        );
      },

      // 应用筛选
      applyFilters() {
        this.filteredEntries = this.dictionaryEntries.filter(entry => {
          // 类别筛选
          if (this.filters.category && entry.dictType !== this.filters.category) {
            return false;
          }

          // 状态筛选
          if (this.filters.active === 'active' && !entry.active) {
            return false;
          }
          if (this.filters.active === 'inactive' && entry.active) {
            return false;
          }

          // 数据类型筛选
          if (this.filters.dataType && entry.dictValue !== this.filters.dataType) {
            return false;
          }

          // 时间范围筛选
          if (this.filters.timeRange) {
            const now = new Date();
            const entryDate = new Date(entry.createTime);

            if (this.filters.timeRange === 'week') {
              const oneWeekAgo = new Date();
              oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
              if (entryDate < oneWeekAgo) return false;
            } else if (this.filters.timeRange === 'month') {
              const oneMonthAgo = new Date();
              oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
              if (entryDate < oneMonthAgo) return false;
            } else if (this.filters.timeRange === 'year') {
              const oneYearAgo = new Date();
              oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
              if (entryDate < oneYearAgo) return false;
            }
          }

          return true;
        });

        this.currentPage = 1;
      },

      // 解析数据库中的日期格式 (dd/MM/yyyy HH:mm:ss)
      parseDate(dateString) {
        if (!dateString) return null;

        const parts = dateString.split(' ');
        const dateParts = parts[0].split('/');
        const timeParts = parts[1] ? parts[1].split(':') : ['0', '0', '0'];

        return new Date(
                parseInt(dateParts[2]),  // 年
                parseInt(dateParts[1]) - 1, // 月 (0-11)
                parseInt(dateParts[0]),  // 日
                parseInt(timeParts[0]),  // 时
                parseInt(timeParts[1]),  // 分
                parseInt(timeParts[2])   // 秒
        );
      },

      // 格式化日期显示
      formatDate(dateString) {
        const date = this.parseDate(dateString);
        if (!date) return '';

        return date.toLocaleDateString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        });
      },

      fetchDictionaryEntries() {
        this.loading = true;
        axios.get('/api/dict/all')
                .then(response => {
                  this.dictionaryEntries = response.data;
                  this.filteredEntries = [...this.dictionaryEntries];
                  this.loading = false;
                })
                .catch(error => {
                  console.error('获取数据字典失败:', error);
                  this.loading = false;
                  alert('获取数据字典失败，请稍后重试');
                });
      },

      openAddModal() {
        this.currentEntry = {
          dict_name: '',
          dict_code: '',
          dict_type: 'customer_type',
          dict_value: '',
          sort: 1,
          status: '1'
        };
        this.isAdding = true;
        this.showModal = true;
      },

      openEditModal(entry) {
        this.currentEntry = {...entry};
        this.isAdding = false;
        this.showModal = true;
      },

      saveEntry() {
        // 验证必填字段
        if (!this.currentEntry.dict_name) {
          alert('数据项名称不能为空');
          return;
        }
        if (!this.currentEntry.dict_code) {
          alert('数据项编码不能为空');
          return;
        }
        if (!this.currentEntry.dict_type) {
          alert('请选择数据类别');
          return;
        }
        if (!this.currentEntry.dict_value) {
          alert('请输入数据值');
          return;
        }

        // 根据操作类型调用相应API
        const apiUrl = this.isAdding ? '/api/dict' : '/api/dict';
        const method = this.isAdding ? 'post' : 'put';

        // 准备发送的数据
        const dataToSend = {
          dict_id: this.currentEntry.dict_id,
          dict_name: this.currentEntry.dict_name,
          dict_code: this.currentEntry.dict_code,
          dict_type: this.currentEntry.dict_type,
          dict_value: this.currentEntry.dict_value,
          sort: this.currentEntry.sort || 1,
          status: this.currentEntry.status
        };

        axios[method](apiUrl, dataToSend)
                .then(response => {
                  this.fetchDictionaryEntries();
                  this.showModal = false;
                  alert(`数据项 ${this.currentEntry.dict_name} ${this.isAdding ? '已添加' : '已更新'}！`);
                })
                .catch(error => {
                  console.error('保存失败:', error);
                  alert('保存失败，请稍后重试');
                });
      },

      deleteEntry(id) {
        if (!confirm('确定要删除此数据项吗？此操作不可撤销。')) return;

        axios.delete(`/api/dict/${id}`)
                .then(response => {
                  this.fetchDictionaryEntries();
                  alert('数据项已删除！');
                })
                .catch(error => {
                  console.error('删除失败:', error);
                  alert('删除失败，请稍后重试');
                });
      },

      toggleEntryStatus(entry) {
        const newStatus = entry.status === '1' ? '0' : '1';
        const dataToSend = {...entry, status: newStatus};

        axios.put('/api/dict', dataToSend)
                .then(response => {
                  entry.status = newStatus;
                  alert(`数据项 ${entry.dict_name} 已${newStatus === '1' ? '启用' : '停用'}！`);
                })
                .catch(error => {
                  console.error('状态更新失败:', error);
                  alert('状态更新失败，请稍后重试');
                });
      },


      // 关闭模态框
      closeModal() {
        this.showModal = false;
      },


      // 分页方法
      nextPage() {
        if (this.currentPage < this.totalPages) {
          this.currentPage++;
        }
      },

      prevPage() {
        if (this.currentPage > 1) {
          this.currentPage--;
        }
      },

    }
  });
</script>
</body>
</html>